package com.tbl.modules.platform.service.impl.system;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.Query;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.constant.OperationCode;
import com.tbl.modules.platform.dao.system.MenuDAO;
import com.tbl.modules.platform.dao.system.RoleDAO;
import com.tbl.modules.platform.dao.system.RoleMenuDAO;
import com.tbl.modules.platform.dao.system.RoleMenuOperationDAO;
import com.tbl.modules.platform.entity.system.Menu;
import com.tbl.modules.platform.entity.system.Role;
import com.tbl.modules.platform.entity.system.RoleMenuOperation;
import com.tbl.modules.platform.service.system.RoleService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色接口实现
 * @author 70486
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleDAO, Role> implements RoleService {

    /**
     * 角色DAO
     */
    @Autowired
    private RoleDAO roleDAO;
    /**
     * 角色菜单DAO
     */
    @Autowired
    private RoleMenuDAO roleMenuDAO;
    /**
     * 角色操作
     */
    @Autowired
    private RoleMenuOperationDAO roleMenuOperationDAO;

    /**
     * 下拉列表获取所有角色列表
     * @param params
     * @return Map<String, Object>
     */
    @Override
    public List<Map<String, Object>> getRoleList(Map<String, Object> params) {
        return roleDAO.getRoleList(params);
    }

    /**
     * 获取所有角色分页列表
     * @param pageTbl
     * @param params
     * @return PageUtils
     */
    @Override
    public PageUtils getRolePageListS(PageTbl pageTbl, Map<String, Object> params) {
        Page<Map<String, Object>> page = new Page<>(pageTbl.getPageno(), pageTbl.getPagesize());
        List<Map<String, Object>> mapList = roleDAO.selectRoleListS(page, params);
        List<Map<String, Object>> mList = new ArrayList<>();
        mapList.forEach(a -> {
            Map<String, Object> map = new HashMap<>(2);
            map.put("id", a.get("id"));
            map.put("text", a.get("text"));
            mList.add(map);
        });
        return new PageUtils(page.setRecords(mList));
    }

    /**
     * 查询角色信息
     * @param params
     * @return PageUtils
     */
    @Override
    public PageUtils getRolePageListS1(Map<String, Object> params) {
        Page<Role> page = this.selectPage(new Query<Role>(params).getPage(), new EntityWrapper<>());
        return new PageUtils(page.setRecords(roleDAO.selectRoleListS1(page, params)));
    }

    /**
     * 获取角色列表
     * @return Map<String, Object>
     */
    @Override
    public List<Map<String, Object>> getRoles() {
        return roleDAO.getRoles();
    }

    /**
     * 根据角色主键获取角色菜单
     * @param rid
     * @param type
     * @param notInMenuNumber
     * @param menuNumber
     * @return List<Map>
     */
    @Override
    public List<Map<String, Object>> getMenuListByRid(Long rid, Integer type, Integer notInMenuNumber, Integer menuNumber) {
        List<Map<String, Object>> list = null;
        if (type == 1) {
            if (rid != null) {
                list = roleDAO.getMenuListByRidOne(rid, type, notInMenuNumber);
                Map<String, ? extends Object> rootm = ImmutableMap.of("id", "M0", "pId", "M-1", "name", "所有菜单", "checked", false);
                List<Map<String, Object>> alllist = Lists.newArrayList();
                alllist.add((Map<String, Object>) rootm);
                alllist.addAll(list);
                return alllist;
            } else {
                list = roleDAO.getMenuListByRidTwo(type,notInMenuNumber);
            }
        } else if (type == 2 || type == 3) {
            if (rid != null) {
                list = roleDAO.getMenuListByRidThree(rid, type, menuNumber);
                Map<String, ? extends Object> rootm = ImmutableMap.of("id", "0", "pId", "-1", "name", "所有菜单", "checked", false);
                List<Map<String, Object>> alllist = Lists.newArrayList();
                alllist.add((Map<String, Object>) rootm);
                alllist.addAll(list);
                return alllist;
            } else {
                list = roleDAO.getMenuListByRidFour(type,menuNumber);
            }
        }
        return list;
    }

    /**
     * 保存信息，并返回主键
     * @param role 角色对象
     * @return Long
     */
    @Override
    public Long saveForGernatedKey(Role role) {
        baseMapper.insert(role);
        return role.getRoleId();
    }

    /**
     * 角色保存/修改
     * @param role
     * @return boolean
     */
    @Override
    public boolean saveRole(Role role) {
        boolean ret = false;
        Long roleId = role.getRoleId();

        // 更新
        if (roleId != null) {
            ret = this.updateById(role);
            // 新增
        } else {
            this.insert(role);
        }
        return ret;
    }

    /**
     * 批量保存角色对应菜单信息
     * @param roleId 角色ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delRoleMenuByRoleId(long roleId, Integer type) {
        roleMenuDAO.deleteByType(roleId, type);
        if (type == 1) {
            Map<String, Object> oMap = new HashMap<>(1);
            roleMenuDAO.deleteOperationByType(roleId,1,2);
/*            oMap.put("ROLEID", roleId);
            roleMenuOperationDAO.deleteByMap(oMap);*/
        }else if(type == 4){
            Map<String, Object> oMap = new HashMap<>(1);
            roleMenuDAO.deleteOperationByType(roleId,1,1);
        }
    }

    /**
     * 批量保存角色对应菜单信息
     * @param roleId  角色ID
     * @param menuIds 菜单ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRoleMenu(long roleId, String[] menuIds, Integer type) {
        boolean flag = false;
        if (type == 1 || type == 4) {
            List<String> mIds = new ArrayList<>();
            List<String> oIds = new ArrayList<>();
            Arrays.stream(menuIds).collect(Collectors.toList()).forEach(a -> {
                if (a.contains("M")) {
                    mIds.add(a);
                } else if (a.contains("O")) {
                    oIds.add(a);
                }
            });
            List<Long> mIds1 = mIds.stream().map(a -> a.substring(1)).map(Long::parseLong).collect(Collectors.toList());
            List<Long> oIds1 = oIds.stream().map(a -> a.substring(1)).map(Long::parseLong).collect(Collectors.toList());

            Map<String, Object> map;
            for (Long aLong : mIds1) {
                map = new HashMap<>(2);
                map.put("roleId", roleId);
                map.put("menuId", aLong);
                flag = roleMenuDAO.saveRoleMenu(map);
            }

            Map<String, Object> oMap;
            for (Long aLong : oIds1) {
                oMap = new HashMap<>(2);
                oMap.put("moId", aLong);
                oMap.put("roleId", roleId);
                flag = roleMenuDAO.saveRoleMenuOperation(oMap);
            }
        } else if (type == 2 || type == 3 || type == 5) {
            Map<String, Object> map;
            for (String menuId : menuIds) {
                map = new HashMap<>(2);
                map.put("roleId", roleId);
                map.put("menuId", Long.parseLong(menuId));
                flag = roleMenuDAO.saveRoleMenu(map);
            }
        }
        return flag;
    }

    /**
     * 根据角色主键获取角色名称
     * @param ids
     * @return String
     */
    @Override
    public String getRoleNameByRoleids(String ids) {
        StringBuilder rolename = new StringBuilder();
        if (StringUtils.isNotEmpty(ids)) {
            List<Long> lstId = Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            List<Role> lstRole = baseMapper.selectBatchIds(lstId);
            for (Role role : lstRole) {
                rolename.append(role.getRoleName()).append(",");
            }
            if (!StringUtils.isEmpty(rolename.toString())) {
                rolename = new StringBuilder(rolename.substring(0, rolename.length() - 1));
            }
        }
        return rolename.toString();
    }

    /**
     * 查询存在用户的角色列表
     * @param ids 角色id
     * @return Role
     */
    @Override
    public List<Role> isHasRoleUser(String ids) {
        List<Role> roleList = new ArrayList<>();
        if (!StringUtils.isEmptyString(ids)) {
            List<Long> lstId = Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            roleList = roleDAO.isHasRoleUser(lstId);
        }
        return roleList;
    }

    /**
     * 删除角色信息
     * @param ids
     * @return boolean
     */
    @Override
    public boolean delRole(String ids) {
        return this.deleteBatchIds(Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()));
    }

    /**
     * 查询是否有相同名称的角色
     * @param name 角色名称
     * @param rid
     * @return boolean
     */
    @Override
    public boolean isHasRoleByName(String name, String rid) {
        boolean ret = false;
        if (!StringUtils.isEmptyString(name)) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("roleName", name);
            map.put("roleId", rid);

            Integer total = roleDAO.isHasRoleByName(map);
            int count = (total == null ? 0 : total);
            if (count > 0) {
                ret = true;
            }
        }
        return ret;
    }

    /**
     * 角色菜单权限查询
     * @param roleId
     * @param menuId
     * @return OperationCode
     */
    @Override
    public OperationCode selectOperationByRoleId(Long roleId, Long menuId) {
        OperationCode code = new OperationCode();
        roleMenuDAO.selectOperationByRoleId(roleId, menuId).forEach(a -> {
            if (a.get("CODE") != null && !"".equals(a.get("CODE"))) {
                if ("web_search".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebSearch(1);
                } else if ("web_add".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebAdd(1);
                } else if ("web_edit".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebEdit(1);
                } else if ("web_del".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebDel(1);
                } else if ("web_disable".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebDisable(1);
                } else if ("web_enable".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebEnable(1);
                } else if ("web_export".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebExport(1);
                } else if ("web_info".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebInfo(1);
                } else if ("web_confirm".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebConfirm(1);
                } else if ("web_execute".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebExecute(1);
                } else if ("web_freeze".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebFreeze(1);
                } else if ("web_thaw".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebThaw(1);
                } else if ("web_review".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebReview(1);
                }else if ("web_effective".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebEffective(1);
                } else if ("web_invalid".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebInvalid(1);
                } else if ("web_print".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebPrint(1);
                } else if ("web_reprint".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebRePrint(1);
                } else if ("web_qacode_change".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebQacodeChange(1);
                } else if ("web_tbsj".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebTbsj(1);
                } else if ("web_outstorage".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebOutstorage(1);
                } else if ("web_instorage".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebInstorage(1);
                } else if ("web_free".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebFree(1);
                } else if ("web_unmultiplexing".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebUnmultiplexing(1);
                } else if ("web_multiplexing".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebMultiplexing(1);
                } else if ("web_allclear".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebAllclear(1);
                } else if ("web_package".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebPackage(1);
                } else if ("web_confirm_outstorage".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebConfirmOutstorage(1);
                } else if ("web_cancel_outstorage".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebCancelOutstorage(1);
                } else if ("web_manul_warehouse".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebManulWarehouse(1);
                } else if ("web_binding_card".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebBindingCard(1);
                } else if ("web_reupload".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebReupload(1);
                } else if ("web_cancelupload".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebCancelupload(1);
                } else if ("web_discard_shelf".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebDiscardShelf(1);
                } else if ("web_active_shelf".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebActiveShelf(1);
                } else if ("web_bu_print".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebBuPrint(1);
                } else if ("web_return_storage".equalsIgnoreCase(a.get("CODE").toString())) {
                    code.setWebReturnStorage(1);
                }

            }
        });
        return code;
    }

    /**
     * 更新菜单下的按钮权限
     * @param menuId 菜单主键
     */
    @Override
    public void updateByMenuId(Long menuId){
        roleDAO.updateByMenuId(menuId);
    }

    /**
     * 更新菜单下的按钮权限
     * @param menuId 菜单主键
     */
    @Override
    public void setBakByMenuId(Long menuId){
        roleDAO.setBakByMenuId(menuId);
    }


}
